package org.googlecode.viewt.core.tools.web;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.googlecode.viewt.core.tools.formbean.FormBeanCfgRepository;
import org.googlecode.viewt.core.tools.formbean.types.FormBeanDef;
import org.googlecode.viewt.core.tools.formbean.types.PropertyDef;
import org.googlecode.viewt.core.tools.web.types.Action;
import org.googlecode.viewt.core.tools.web.types.Actions;
import org.googlecode.viewt.core.tools.web.types.InterceptorDef;
import org.googlecode.viewt.core.tools.web.types.InterceptorsItem;

import xjavadoc.SourceClass;

public class WebActionUtil {
	public static String firstUpper(String propName) {
		return propName.substring(0, 1).toUpperCase() + propName.substring(1);
	}

	public static String shortClassName(String className) {
		return className.substring(className.lastIndexOf(46) + 1);
	}

	public static String getPackagePath(String basePath, String className) {
		String[] packageSeg = getPackageName(className).split("[.]");
		String path = "";
		for (int i = 0; i < packageSeg.length; ++i) {
			if (i != 0)
				path = path + File.separator;
			path = path + packageSeg[i];
		}

		if (basePath != null) {
			path = basePath + File.separator + path;
		}
		return path;
	}

	public static String shortJavaFileName(String className) {
		return shortClassName(className) + ".java";
	}

	public static String fullJavaFileName(String basePath, String className) {
		return getPackagePath(basePath, className) + File.separator
				+ shortJavaFileName(className);
	}

	public static String getPackageName(String className) {
		int index = className.lastIndexOf(46);
		if (index < 0) {
			return null;
		}
		return className.substring(0, index);
	}

	public static String findSource(String[] paths, String className) {
		if ((paths == null) || (className == null)) {
			return null;
		}
		String javaFile = className.replace('.', File.separatorChar) + ".java";
		for (int i = 0; i < paths.length; ++i) {
			String fileName = null;
			if (paths[i].endsWith(File.separator))
				fileName = paths[i] + javaFile;
			else {
				fileName = paths[i] + File.separator + javaFile;
			}
			File source = new File(fileName);
			if (source.exists()) {
				return fileName;
			}
		}
		return null;
	}

	public static String impActionClass(String prePackName, String projectName,
			String moduleName, String actionName) {
		return prePackName.toLowerCase() + "." + projectName.toLowerCase()
				+ "." + moduleName.toLowerCase() + ".bs.action."
				+ firstUpper(actionName) + "Action";
	}

	public static String actionBeanName(String projectName, String moduleName,
			String actionName) {
		return projectName + "_" + moduleName + "_" + actionName + "_Action";
	}

	public static String actionTargetName(String projectName,
			String moduleName, String actionName) {
		return projectName + "_" + moduleName + "_" + actionName
				+ "_Action_Target";
	}

	public static String actionBeanConfigFile(String destPath, String moduleName) {
		if (destPath.endsWith(File.separator)) {
			return destPath + "bs" + File.separator + moduleName
					+ "_Action.spc.xml";
		}
		return destPath + File.separator + "bs" + File.separator + moduleName
				+ "_Action.spc.xml";
	}

	public static String formBeanRelationFile(String destPath, String moduleName) {
		if (destPath.endsWith(File.separator)) {
			return destPath + "act-bean" + File.separator + moduleName + ".xml";
		}
		return destPath + File.separator + "act-bean" + File.separator
				+ moduleName + ".xml";
	}

	public static String webworkConfigFile(String destPath, String moduleName) {
		if (destPath.endsWith(File.separator)) {
			return destPath + moduleName + ".webwork.xml";
		}
		return destPath + File.separator + moduleName + ".webwork.xml";
	}

	public static String validationConfigFile(String destPath,
			String prePackName, String projectName, String moduleName,
			String actionName) {
		String actionFile = fullJavaFileName(destPath, impActionClass(
				prePackName, projectName, moduleName, actionName));
		return actionFile.substring(0, actionFile.length() - 5)
				+ "-validation.xml";
	}

	public static boolean isImplExtendsDataService(String prePackName,
			String projectName, String moduleName, String[] paths,
			String implClassName) {
		String impFileName = findSource(paths, implClassName);
		SourceClass implClass = org.googlecode.viewt.core.tools.JavaSourceParser
				.parseFile(impFileName)[0];

		String dsClassName = prePackName + "." + projectName + "." + moduleName
				+ ".bl.Base" + firstUpper(moduleName) + "DataService";

		return implClass.isSubclassOf(dsClassName);
	}

	public static String[] formbeanFileProps(Action actionDef,
			FormBeanCfgRepository formbeanRepository) {
		if ((actionDef == null) || (actionDef.getFormBeanDef() == null)) {
			return null;
		}
		String formbeanClass = actionDef.getFormBeanDef().getClassName();
		FormBeanDef formbeanDef = formbeanRepository
				.getFormBeanConfig(formbeanClass);
		if (formbeanDef == null) {
			return null;
		}

		List fileList = new ArrayList();
		PropertyDef[] propDefs = formbeanDef.getPropertyDef();
		for (int i = 0; i < propDefs.length; ++i) {
			if ("java.io.File".equals(propDefs[i].getJavaType())) {
				fileList.add(propDefs[i].getName());
			}
		}
		if (fileList.size() == 0) {
			return null;
		}
		return ((String[]) fileList.toArray(new String[0]));
	}

	public static boolean containsValidationDef(Actions actionsDef,
			String actionName) {
		if (actionsDef == null) {
			return false;
		}
		Action[] actions = actionsDef.getAction();
		int actionSize = (actions == null) ? 0 : actions.length;
		for (int i = 0; i < actionSize; ++i) {
			if (actions[i].getName().equals(actionName)) {
				return ((actions[i].getFormBeanDef() == null)
						|| (actions[i].getFormBeanDef().getBeanValidator() == null) || (actions[i]
						.getFormBeanDef().getBeanValidator()
						.getValidateFieldsItem() == null));
			}

		}

		return false;
	}

	public static boolean containInterceptorDef(Actions actionsDef) {
		if (actionsDef == null) {
			return false;
		}

		Action[] actions = actionsDef.getAction();
		int actionSize = (actions == null) ? 0 : actions.length;
		for (int i = 0; i < actionSize; ++i) {
			if (actions[i].getBeforeICsDef() != null) {
				InterceptorsItem[] items = actions[i].getBeforeICsDef()
						.getInterceptorsItem();
				int itemSize = (items == null) ? 0 : items.length;
				for (int j = 0; j < itemSize; ++j) {
					if ((items[j].getInterceptorsChoice() != null)
							&& (items[j].getInterceptorsChoice()
									.getInterceptorDef() != null)) {
						return true;
					}
				}
			}

			if (actions[i].getAfterICsDef() == null)
				continue;
			InterceptorsItem[] items = actions[i].getAfterICsDef()
					.getInterceptorsItem();
			int itemSize = (items == null) ? 0 : items.length;
			for (int j = 0; j < itemSize; ++j) {
				if ((items[j].getInterceptorsChoice() != null)
						&& (items[j].getInterceptorsChoice()
								.getInterceptorDef() != null)) {
					return true;
				}
			}
		}

		return false;
	}

	public static InterceptorDef[] getInterceptorDefs(Actions actionsDef) {
		Map interceptorMap = new HashMap();

		Action[] actions = actionsDef.getAction();
		int actionSize = (actions == null) ? 0 : actions.length;
		for (int i = 0; i < actionSize; ++i) {
			InterceptorDef def;
			if (actions[i].getBeforeICsDef() != null) {
				InterceptorsItem[] items = actions[i].getBeforeICsDef()
						.getInterceptorsItem();
				int itemSize = (items == null) ? 0 : items.length;
				for (int j = 0; j < itemSize; ++j) {
					if ((items[j].getInterceptorsChoice() == null)
							|| (items[j].getInterceptorsChoice()
									.getInterceptorDef() == null))
						continue;
					def = items[j].getInterceptorsChoice().getInterceptorDef();
					interceptorMap.put(def.getName(), def);
				}

			}

			if (actions[i].getAfterICsDef() == null)
				continue;
			InterceptorsItem[] items = actions[i].getAfterICsDef()
					.getInterceptorsItem();
			int itemSize = (items == null) ? 0 : items.length;
			for (int j = 0; j < itemSize; ++j) {
				if ((items[j].getInterceptorsChoice() == null)
						|| (items[j].getInterceptorsChoice()
								.getInterceptorDef() == null))
					continue;
				def = items[j].getInterceptorsChoice().getInterceptorDef();
				interceptorMap.put(def.getName(), def);
			}

		}

		return ((InterceptorDef[]) interceptorMap.values().toArray(
				new InterceptorDef[0]));
	}
}